﻿using Futaba.SBus.Readers;
using Futaba.SBus.Telemetry;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace Futaba.SBus.Tests
{
	[TestClass]
	public class SbusParsingServiceTests : BaseTest
	{

		[TestMethod, TestCategory("Integration")]
		[DeploymentItem(@"Samples\TBoxData\flight2.log")]
		[DeploymentItem(@"Samples\TBoxData\flight2.xml")]
		public void TelemetryOnly()
		{
			var reader = new FileSbusStreamReader("flight2.log", packetsPerSecond: 0);
			var slots = LoadSlots();
			var target = new SbusParsingService();
			target.TelemetryParser.ItemsCollection = slots;
			target.ChannelParser.ItemsCollection = Channels.ChannelFactory.DefaultInstance.GetDefaultChannels();

			int starting = 0, started = 0, stopping = 0, stopped = 0;
			target.Starting += (o, e) => starting++;
			target.Started += (o, e) => { started++; Assert.IsTrue(target.IsRunning); };
			target.Stopping += (o, e) => stopping++;
			target.Stopped += (o, e) => { stopped++; Assert.IsFalse(target.IsRunning); };

			int itemsUpdated = 0, packetsReceived = 0;
			target.TelemetryParser.ItemsUpdated += (o, e) => itemsUpdated++;
			target.TelemetryParser.DataReceived += (o, e) => packetsReceived++;
			target.TelemetryParser.ItemUpdated += (o, e) => TestContext.WriteLine("{0}", e);

			target.Start(reader, false, true);
			Thread.Sleep(100);
			target.Stop().Wait();

			Assert.AreEqual(1, starting);
			Assert.AreEqual(1, started);
			Assert.AreEqual(1, stopping);
			Assert.AreEqual(1, stopped);

			Assert.AreNotEqual(0, itemsUpdated);
			Assert.AreNotEqual(0, packetsReceived);
			Assert.AreEqual(0, target.TelemetryParser.BytesSkipped);
			Assert.AreEqual(0, target.TelemetryParser.PacketErrors);
			Assert.AreEqual(0, target.TelemetryParser.SequenceErrors);
		}

		private List<ISlot> LoadSlots()
		{
			using (var stream = File.OpenRead("flight2.xml"))
			{
				var slots = SlotFactory.DefaultInstance.Load(stream).Cast<ISlot>().ToList();
				return slots;
			}
		}

	}
}
